﻿using System;
using System.Collections.Generic;
#if DEBUG
using System.Diagnostics;
#endif // #if DEBUG
using System.Linq;
using System.Text;

using FRL.DebtChased.Extensions;

namespace FRL.DebtChased.Repository.ViewModels
{

	/// <summary>
	/// Declaration of ClientAlertsModel class
	/// </summary>
	[Serializable]
	public class ClientAlertsModel
	{

		/////////////////////////////////////////////////////////////
		// Nested classes

		[Serializable]
		public class Element
		{

			/////////////////////////////////////////////////////////
			// Attributes

			public int ClientAlertId { get; set; }

			public int UserId { get; set; }
			public string UserAsText { get; set; }

			public bool FilterAll { get; set; }
			public string FilterAllAsText
			{
				get
				{
					if (this.FilterAll)
						return "All";
					else
						return "Specific";
				}
			}

			public string ModifiedAsText { get; set; }

			public decimal MinimumAmount { get; set; }
			public string MinimumAmountAsText
			{
				get
				{
					if (this.MinimumAmount <= 0)
						return "[ALL]";
					else
						return this.MinimumAmount.ToString("≥#,0.00");
				}
			}

			/////////////////////////////////////////////////////////
			// Construction

			public Element( int iClientAlertId )
			{

				// Initialize member variables
				this.ClientAlertId = iClientAlertId;

			}

		}

		/////////////////////////////////////////////////////////////
		// Constants and Enumerations

		/////////////////////////////////////////////////////////////
		// Attributes

		private List<Element> m_elements = new List<Element>();
		public List<Element> Elements
		{
			get { return m_elements; }
		}

		private int m_iSendTimeMinutes = 0;
		public int SendTimeMinutes
		{
			get { return m_iSendTimeMinutes; }
			set { m_iSendTimeMinutes = value; }
		}

		/////////////////////////////////////////////////////////////
		// Construction

		public ClientAlertsModel( DebtChasedEntities ent )
		{

			// Load from stored procedure
			var results = ent.ClientAlertsProc();

			// Load the element list
			foreach (var ob in results)
			{

				// Add a new element
				Element el = new Element(ob.fdClientAlertId);
				el.FilterAll = ob.fdFilterAll;
				el.UserId = ob.fdUserId;
				el.UserAsText = ob.fdUserFullName;
				if(ob.fdModifiedAt != null)
					el.ModifiedAsText = string.Format("{0} by {1}",
					ob.fdModifiedAt.Value.ToCuteString(),
					ob.fdModifiedBy
				);
				m_elements.Add(el);

			}

			// Get send time
			m_iSendTimeMinutes = SystemConfig.GetClientAlertSendTimeMinutes(ent);

		}

		/////////////////////////////////////////////////////////////
		// Operations

		public string Set( DebtChasedEntities ent, int iUserId )
		{

			// Declare return variable
			string strError = null;

			try
			{

				// Save the send time
				int iCurrentSendTimeMinutes = SystemConfig.GetClientAlertSendTimeMinutes(ent);
				if (iCurrentSendTimeMinutes != m_iSendTimeMinutes)
				{
					SystemConfig sc = ent.SystemConfigs.First();
					sc.ClientAlertSendTimeMinutes = m_iSendTimeMinutes;
				}

				// Get the existing status list
				List<ClientAlert> current = (from ca in ent.ClientAlerts select ca).ToList();

				// Update the current items
				foreach (ClientAlert clientAlert in current)
				{

					// Find in the model
					ClientAlertsModel.Element modelElement = this.FindByClientAlertId(clientAlert.ClientAlertId);

					// If model element found...
					if (modelElement != null)
					{

						// Compare details
						if (
							(modelElement.FilterAll != clientAlert.FilterAll)
							||
							(modelElement.UserId != clientAlert.UserId)
						)
						{

							// Update the alert
							clientAlert.FilterAll = modelElement.FilterAll;
							clientAlert.UserId = modelElement.UserId;

						}

					}
					else
					{

						// Alert has been deleted
						ent.ClientAlerts.DeleteObject(clientAlert);

					}

				}

				// Add new alert
				foreach (ClientAlertsModel.Element el in this.Elements)
				{

					// If this status has a zero or negative 
					if (el.ClientAlertId <= 0)
					{

						// Add a new status to the database
						ClientAlert newAlert = ClientAlert.CreateClientAlert(
							0, 
							el.UserId, 
							el.FilterAll
						);
						ent.ClientAlerts.AddObject(newAlert);

					}

				}

				// Save changes to the database
				ent.SaveChanges();

			}
			catch (Exception x)
			{

				// Process exception
				strError = ErrorProcessing.HandleException(x, "save client alert", iUserId);

			}

			// Return variable
			return strError;

		}

		public int GetNextNewId()
		{

			// Declare return variable
			int iFtmp = 0;

			// Find the lowest id
			foreach (Element el in m_elements)
				iFtmp = Math.Min(iFtmp,el.ClientAlertId);
			iFtmp--;

			// Return variable
			return iFtmp;

		}

		public Element FindByClientAlertId(int iClientAlertId)
		{

			// Declare return variable
			Element Ftmp = null;

			// Loop through the elements
			foreach (Element el in m_elements)
			{
				if (el.ClientAlertId == iClientAlertId)
				{
					Ftmp = el;
					break;
				}
			}

			// Return variable
			return Ftmp;

		}

	}

}
